package interactiond

import (
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/common"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/log"
)

var (
	_ TypeAggregateRoot = &typeAggregateRoot{}
)

const (
	// Type 互动类型标识
	Type = "type"
)

func initType(d ddd.Domain, repo TypeRepo) {
	car := &typeAggregateRoot{}
	car.Init(car, d, Type)
	repo.Init(repo, car, Type)
}

// TypeAggregateRoot 互动类型聚合根
type TypeAggregateRoot interface {

	// 创建评论组
	// 发出添加评论组事件
	CreType(ctx ddd.Context, desc TypeDesc) (err error)

	// 分页获取当前互动类型列表
	QueryPage(ctx ddd.Context, is TypeSearch, pi common.PageInfo) (pr common.PageResult, result []TypeAggregate, err error)

	// 通过id获取互动类型
	GetType(ctx ddd.Context, code string) (*TypeAggregate, error)
	// 获取互动模式
	All(ctx ddd.Context) (result []TypeAggregate, err error)

	// 是否存在指定互动名称
	// name 名称 code 排除指定编号的互动类型
	ExistNameByCode(ctx ddd.Context, name, code string) (bool, error)
	// 是否存在指定的Code
	ExistCode(ctx ddd.Context, code string) (bool, error)
}

// TypeSearch 类型搜搜
type TypeSearch struct {
	Key    string
	Status []ITStatus
}

// TypeRepo 互动类型仓储
type TypeRepo interface {
	ddd.Repository
	// 新增类型
	AddType(ctx ddd.Context, itype TypeDesc) (err error)
	// 获取指定类型：根据唯一标识获取类型实体
	GetType(ctx ddd.Context, code string) (*TypeAggregate, error)
	// 分页获取类型列表：根据唯一标识获取下一页指定数量的类型实体集合
	// total 总数量
	QueryPage(ctx ddd.Context, is TypeSearch, pi common.PageInfo) (pr common.PageResult, result []TypeAggregate, err error)

	All(ctx ddd.Context, is TypeSearch) (result []TypeAggregate, err error)
	// 修改类型
	UpdateType(ctx ddd.Context, code string, itype *TypeDesc) error
	// 删除类型 标记删除
	DeleteType(ctx ddd.Context, code string) error
	// 锁定类型
	LockType(ctx ddd.Context, code string) error
	// 解锁类型
	UnlockType(ctx ddd.Context, code string) error
	// 恢复类型
	RecoverType(ctx ddd.Context, code string) error
	// 彻底删除指定类型
	DestroyType(ctx ddd.Context, code string) error

	ExistNameByCode(ctx ddd.Context, name, code string) (bool, error)
	ExistCode(ctx ddd.Context, code string) (bool, error)
}

// TypeAggregate 互动类型聚合根
type TypeAggregate struct {
	ddd.BaseAggregate
	TypeDesc `json:"desc"`
	Operator `json:"operator"`
}

func (a *TypeAggregate) handlerEvtActData(ctx ddd.Context, evtact string, handler func() error) error {
	edata := &EvtActTypeData{
		Old: *a,
	}
	err := handler()
	if err != nil {
		return err
	}
	edata.New, err = a.Repo().GetType(ctx, a.Code)
	if err != nil {
		log.Warnf("更新完成后获取信息失败：%v", err)
		return nil
	}
	a.Trigger(ctx, EvtTypType, evtact, edata)
	return err
}

// Repo 获取聚合对应的仓储
func (a *TypeAggregate) Repo() TypeRepo {
	return a.Repository().(TypeRepo)
}

// UpdateDesc 修改互动类型中的描述信息
// 发出修改信息互动类型事件
func (a *TypeAggregate) UpdateDesc(ctx ddd.Context, desc *TypeDesc) error {
	return a.handlerEvtActData(ctx, EvtActUpdate, func() error {
		return a.Repo().UpdateType(ctx, a.Code, desc)
	})

}

// Delete 删除互动类型
// 发出删除信息组事件
func (a *TypeAggregate) Delete(ctx ddd.Context) error {
	return a.handlerEvtActData(ctx, EvtActDelete, func() error {
		return a.Repo().DeleteType(ctx, a.Code)
	})
}

// Destroy 彻底删除互动类型
// 发出彻底删除互动类型事件
func (a *TypeAggregate) Destroy(ctx ddd.Context) error {
	return a.handlerEvtActData(ctx, EvtActDestroy, func() error {
		return a.Repo().DestroyType(ctx, a.Code)
	})

}

// Lock 锁定互动类型
// 发出Lock信息组事件
func (a *TypeAggregate) Lock(ctx ddd.Context) error {
	return a.handlerEvtActData(ctx, EvtActLock, func() error {
		return a.Repo().LockType(ctx, a.Code)
	})
}

// Unlock 解锁互动类型
// 发出Unlock信息组事件
func (a *TypeAggregate) Unlock(ctx ddd.Context) error {
	return a.handlerEvtActData(ctx, EvtActUnlock, func() error {
		return a.Repo().UnlockType(ctx, a.Code)
	})
}

// Recover 解锁互动类型
// 发出Unlock信息组事件
func (a *TypeAggregate) Recover(ctx ddd.Context) error {
	return a.handlerEvtActData(ctx, EvtActRecover, func() error {
		return a.Repo().RecoverType(ctx, a.Code)
	})
}

type typeAggregateRoot struct {
	ddd.BaseAggregateRoot
}

func (t *typeAggregateRoot) Repo() TypeRepo {
	return t.Repository().(TypeRepo)
}

// 创建评论组
// 发出添加评论组事件
func (t typeAggregateRoot) CreType(ctx ddd.Context, desc TypeDesc) (err error) {
	err = t.Repo().AddType(ctx, desc)
	t.Trigger(ctx, EvtTypType, EvtActAdd, desc)
	return
}

// 分页获取当前互动类型列表
func (t typeAggregateRoot) QueryPage(ctx ddd.Context, is TypeSearch, pi common.PageInfo) (pr common.PageResult, result []TypeAggregate, err error) {
	return t.Repo().QueryPage(ctx, is, pi)
}

// 通过id获取互动类型
func (t typeAggregateRoot) GetType(ctx ddd.Context, code string) (*TypeAggregate, error) {
	return t.Repo().GetType(ctx, code)
}

// 获取系统的互动模式
// org 不为空字符串则获取组织和系统开放的所有互动方式
func (t typeAggregateRoot) All(ctx ddd.Context) (result []TypeAggregate, err error) {
	return t.Repo().All(ctx, TypeSearch{})
}

// 是否存在指定互动名称
// name 名称 code 排除指定编号的互动类型
func (t typeAggregateRoot) ExistNameByCode(ctx ddd.Context, name, code string) (bool, error) {
	return t.Repo().ExistNameByCode(ctx, name, code)
}

// 是否存在指定的Code
func (t typeAggregateRoot) ExistCode(ctx ddd.Context, code string) (bool, error) {
	return t.Repo().ExistCode(ctx, code)
}
